
import java.util.*;


@SuppressWarnings("unchecked")

class ServerSimulation {
	private FIFOQueue myQueue;
	private Queue mySJFQueue;
	private int kiloByteRate;
	
	/**	
       The constructor should create numObjects of WebObjects. Each WebObject represents a Web page 
	 * or other object request by a user. Each of these should be copied. One of them should be enqueued 
	 * in the Heap, a SJF queue, and the other in the FifoQueue. The kiloByteRate defines the speed of the 
	 * Web server�s connection in terms of kilobytes of data per second. It should be stored within a 
	 * private instance variable
   */
	public ServerSimulation(int numObjects, int kiloByteRate)  {
		mySJFQueue =(PriorityQueue) new PriorityQueue<WebObject>();
        myQueue = new FIFOQueue();
        this.kiloByteRate = kiloByteRate;
        
        for (int i=0; i < numObjects; i++){
        	WebObject wo = new WebObject();
        	this.myQueue.enqueue(wo);
        	this.mySJFQueue.offer(wo);
        }
	
	}
	
	/* This method should calculate the average service time for a job on the FIFO-based Web server. 
	 * It should do this by dequeuing each job one at a time. It should then calculate the service time 
	 * for this job by dividing its size in kilobytes by the kilobyte rate of the connection. A running 
	 * total should be kept of the service times. Another running total should be kept that is the sum of 
	 * the service times encountered by each job (the service times of everything before plus the service 
	 * time for the object itself). At the end, dividing this total service time by the number of jobs will 
	 * yield the average service time. 
	 * */

	public int calculateFIFOAverage() {
		// Returns the FIFO average service time per Batch
		int delaySoFar = 0;
		int sumOfDelays = 0;
		int countOfJobs = 0;
		WebObject wo;
		while (!myQueue.isEmpty()){
			wo = (WebObject) myQueue.dequeue();
			countOfJobs++;
			sumOfDelays = sumOfDelays + delaySoFar;
			delaySoFar = delaySoFar + wo.getSize() / this.kiloByteRate;
		}
		
		return sumOfDelays/countOfJobs;
	}

	
	/*This method should do exactly the same thing as calculateFIFOAverage() above, except that it 
	 * operates on the Heap, the priority queue based on job size. 
	 * */


	public int calculateSJFAverage() {
		// Returns the SJF average service time per Batch
		int delaySoFar = 0;
		int sumOfDelays = 0;
		int countOfJobs = 0;
		WebObject wo;
		while (!this.mySJFQueue.isEmpty()){
			wo = (WebObject) this.mySJFQueue.poll();
			countOfJobs++;
			sumOfDelays = sumOfDelays + delaySoFar;
			delaySoFar = delaySoFar + wo.getSize() / this.kiloByteRate;
		}
		
		return sumOfDelays/countOfJobs;
	
	}
	
}